using System;
using System.Collections.Generic;
using Oracle.ManagedDataAccess.Client;
using OracleInternal.Common;

namespace OracleInternal.BinXml
{
	internal class ObxmlDTDInfo : DTDObject
	{
		internal List<DTDElementInfo> m_ElementList = new List<DTDElementInfo>();

		internal List<DTDElementAttributeInfo> m_AttributeList = new List<DTDElementAttributeInfo>();

		internal List<DTDObject> m_ObjectList = new List<DTDObject>();

		private bool m_InitSubset;

		private ObxmlDecodeState m_DecodeState;

		private string m_lastElementString;

		internal bool IsValid;

		internal bool IsExternal;

		internal bool InCDATA;

		internal bool IsEmpty => ObjectName == null;

		internal ObxmlDTDInfo()
		{
			ClearStateObject();
		}

		internal ObxmlDTDInfo(ObxmlDecodeState mDecodeState)
		{
			ClearStateObject();
			SetDecodeStateObject(mDecodeState);
		}

		internal void SetDecodeStateObject(ObxmlDecodeState mDecodeState)
		{
			m_DecodeState = mDecodeState;
		}

		internal bool ProcessAttributes()
		{
			return true;
		}

		internal void InilializeSubset()
		{
			if (!m_InitSubset)
			{
				m_InitSubset = true;
				m_DecodeState.m_CurrentInstruction.AppendString(ObxmlInstructionState.sXmlTagSquareOpen, 0, appendNewLine: true);
			}
		}

		internal bool StartDTD()
		{
			try
			{
				IsValid = true;
				PrintAttributeDecl();
				m_DecodeState.m_CurrentInstruction.AppendStringWithSpaces(ObxmlInstructionState.sXmlDocType, 0, appendSpace: true);
				m_DecodeState.m_CurrentInstruction.AppendString(ObjectName);
				if (!string.IsNullOrEmpty(PublicId))
				{
					m_DecodeState.m_CurrentInstruction.AppendStringWithSpaces(ObxmlInstructionState.sXmlPublic, 0, appendSpace: true, prefixSpace: true);
					m_DecodeState.m_CurrentInstruction.AppendQuoted(PublicId, 0, appendSpace: true);
					m_DecodeState.m_CurrentInstruction.AppendQuoted(SystemId);
				}
				else if (!string.IsNullOrEmpty(SystemId))
				{
					m_DecodeState.m_CurrentInstruction.AppendStringWithSpaces(ObxmlInstructionState.sXmlSystem, 0, appendSpace: true, prefixSpace: true);
					m_DecodeState.m_CurrentInstruction.AppendQuoted(SystemId);
				}
				m_DecodeState.m_IsProcessingDTD = true;
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)285212672, OracleTraceClassName.ObxmlDTDInfo, OracleTraceFuncName.StartDTD, ex);
				throw;
			}
			return true;
		}

		internal bool EndDTD()
		{
			try
			{
				PrintAttributeDecl();
				if (m_InitSubset)
				{
					m_DecodeState.m_CurrentInstruction.AppendString(ObxmlInstructionState.sXmlTagSquareClose);
				}
				m_InitSubset = false;
				m_DecodeState.m_CurrentInstruction.AppendString(ObxmlInstructionState.sXmlTagClosingBracket, 0, appendNewLine: true);
				m_DecodeState.m_IsProcessingDTD = false;
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)285212672, OracleTraceClassName.ObxmlDTDInfo, OracleTraceFuncName.EndDTD, ex);
				throw;
			}
			return true;
		}

		internal bool StartEntity(string name)
		{
			PrintAttributeDecl();
			m_DecodeState.m_CurrentInstruction.AppendEntity(name);
			return true;
		}

		internal bool EndEntity(string name)
		{
			PrintAttributeDecl();
			return true;
		}

		internal bool StartCDATA()
		{
			InCDATA = true;
			return m_DecodeState.m_CurrentInstruction.StartCDATA();
		}

		internal bool EndCDATA()
		{
			bool result = m_DecodeState.m_CurrentInstruction.EndCDATA();
			InCDATA = false;
			return result;
		}

		internal void ElementDecl(DTDElementInfo dtdElement)
		{
			ElementDecl(dtdElement.ElementName, dtdElement.ContentSpec);
		}

		internal void ElementDecl(string name, string model)
		{
			try
			{
				PrintAttributeDecl();
				InilializeSubset();
				m_DecodeState.m_CurrentInstruction.AppendStringWithSpaces(ObxmlInstructionState.sXmlElement, 0, appendSpace: true);
				m_DecodeState.m_CurrentInstruction.AppendStringWithSpaces(name, 0, appendSpace: true);
				m_DecodeState.m_CurrentInstruction.AppendString(model);
				m_DecodeState.m_CurrentInstruction.AppendString(ObxmlInstructionState.sXmlTagClosingBracket, 0, appendNewLine: true);
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)285212672, OracleTraceClassName.ObxmlDTDInfo, OracleTraceFuncName.ElementDecl, ex);
				throw;
			}
		}

		internal void AttributeDecl(DTDElementAttributeInfo attributeInfo)
		{
			if (attributeInfo != null && attributeInfo.ElementName != m_lastElementString)
			{
				PrintAttributeDecl();
			}
			m_AttributeList.Add(attributeInfo);
		}

		internal void AttributeDecl(string elementName, string attributeName, string type, string mode, string value)
		{
			DTDElementAttributeInfo attributeInfo = new DTDElementAttributeInfo(elementName, attributeName, type, mode, value);
			AttributeDecl(attributeInfo);
		}

		internal void EntityDecl(DTDObject entity)
		{
			if (entity.IsParsedEntity)
			{
				InternalEntityDecl(entity.ObjectName, entity.ObjectValue);
			}
			else if (entity.IsUnparsedEntity)
			{
				UnparsedEntityDecl(entity.ObjectName, entity.PublicId, entity.SystemId, entity.Note);
			}
			else
			{
				ExternalEntityDecl(entity.ObjectName, entity.PublicId, entity.SystemId);
			}
		}

		internal void EntityReference(DTDObject entity)
		{
			m_DecodeState.TryAppendingBeginTagClosure(null, checkForInitialNode: true, checkForNewNode: false);
			m_DecodeState.m_CurrentInstruction.AppendEntity(entity.ObjectName);
		}

		internal void InternalEntityDecl(string name, string value)
		{
			try
			{
				PrintAttributeDecl();
				InilializeSubset();
				m_DecodeState.m_CurrentInstruction.AppendStringWithSpaces(ObxmlInstructionState.sXmlEntity, 0, appendSpace: true);
				if (name.StartsWith(ObxmlInstructionState.sXmlPercentage))
				{
					m_DecodeState.m_CurrentInstruction.AppendStringWithSpaces(name.Substring(1, name.Length - 1), 0, ObxmlInstructionState.sXmlWhitespaceBlank, ObxmlInstructionState.sXmlPercentage);
				}
				else
				{
					m_DecodeState.m_CurrentInstruction.AppendStringWithSpaces(name, 0, appendSpace: true);
				}
				m_DecodeState.m_CurrentInstruction.AppendQuoted(value);
				m_DecodeState.m_CurrentInstruction.AppendString(ObxmlInstructionState.sXmlTagClosingBracket, 0, appendNewLine: true);
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)285212672, OracleTraceClassName.ObxmlDTDInfo, OracleTraceFuncName.InternalEntityDecl, ex);
				throw;
			}
		}

		internal void ExternalEntityDecl(string name, string publicId, string systemId)
		{
			try
			{
				PrintAttributeDecl();
				InilializeSubset();
				m_DecodeState.m_CurrentInstruction.AppendStringWithSpaces(ObxmlInstructionState.sXmlEntity, 0, appendSpace: true);
				if (name.StartsWith(ObxmlInstructionState.sXmlPercentage))
				{
					m_DecodeState.m_CurrentInstruction.AppendStringWithSpaces(name.Substring(1, name.Length - 1), 0, ObxmlInstructionState.sXmlWhitespaceBlank, ObxmlInstructionState.sXmlPercentage);
				}
				else
				{
					m_DecodeState.m_CurrentInstruction.AppendStringWithSpaces(name, 0, appendSpace: true);
				}
				if (!string.IsNullOrEmpty(publicId))
				{
					m_DecodeState.m_CurrentInstruction.AppendStringWithSpaces(ObxmlInstructionState.sXmlPublic, 0, appendSpace: true, prefixSpace: true);
					m_DecodeState.m_CurrentInstruction.AppendQuoted(publicId, 0, appendSpace: true);
					m_DecodeState.m_CurrentInstruction.AppendQuoted(systemId);
				}
				else if (!string.IsNullOrEmpty(systemId))
				{
					m_DecodeState.m_CurrentInstruction.AppendStringWithSpaces(ObxmlInstructionState.sXmlSystem, 0, appendSpace: true, prefixSpace: true);
					m_DecodeState.m_CurrentInstruction.AppendQuoted(systemId);
				}
				m_DecodeState.m_CurrentInstruction.AppendString(ObxmlInstructionState.sXmlTagClosingBracket, 0, appendNewLine: true);
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)285212672, OracleTraceClassName.ObxmlDTDInfo, OracleTraceFuncName.ExternalEntityDecl, ex);
				throw;
			}
		}

		internal void UnparsedEntityDecl(string name, string publicId, string systemId, string notationName)
		{
			try
			{
				PrintAttributeDecl();
				InilializeSubset();
				m_DecodeState.m_CurrentInstruction.AppendStringWithSpaces(ObxmlInstructionState.sXmlEntity, 0, appendSpace: true);
				m_DecodeState.m_CurrentInstruction.AppendString(name);
				bool prefixSpace = false;
				if (!string.IsNullOrEmpty(publicId))
				{
					m_DecodeState.m_CurrentInstruction.AppendStringWithSpaces(ObxmlInstructionState.sXmlPublic, 0, appendSpace: true, prefixSpace: true);
					m_DecodeState.m_CurrentInstruction.AppendQuoted(publicId, 0, appendSpace: true);
					m_DecodeState.m_CurrentInstruction.AppendQuoted(systemId);
					prefixSpace = true;
				}
				else if (!string.IsNullOrEmpty(systemId))
				{
					m_DecodeState.m_CurrentInstruction.AppendStringWithSpaces(ObxmlInstructionState.sXmlSystem, 0, appendSpace: true, prefixSpace: true);
					m_DecodeState.m_CurrentInstruction.AppendQuoted(systemId);
					prefixSpace = true;
				}
				m_DecodeState.m_CurrentInstruction.AppendStringWithSpaces(ObxmlInstructionState.sXmlNdata, 0, appendSpace: true, prefixSpace);
				m_DecodeState.m_CurrentInstruction.AppendString(notationName);
				m_DecodeState.m_CurrentInstruction.AppendString(ObxmlInstructionState.sXmlTagClosingBracket, 0, appendNewLine: true);
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)285212672, OracleTraceClassName.ObxmlDTDInfo, OracleTraceFuncName.UnparsedEntityDecl, ex);
				throw;
			}
		}

		internal void NotationDecl(DTDObject note)
		{
			NotationDecl(note.ObjectName, note.PublicId, note.SystemId);
		}

		internal void NotationDecl(string name, string publicId, string systemId)
		{
			try
			{
				PrintAttributeDecl();
				InilializeSubset();
				m_DecodeState.m_CurrentInstruction.AppendStringWithSpaces(ObxmlInstructionState.sXmlNotation, 0, appendSpace: true);
				m_DecodeState.m_CurrentInstruction.AppendString(name);
				if (!string.IsNullOrEmpty(publicId))
				{
					m_DecodeState.m_CurrentInstruction.AppendStringWithSpaces(ObxmlInstructionState.sXmlPublic, 0, appendSpace: true, prefixSpace: true);
					m_DecodeState.m_CurrentInstruction.AppendQuoted(publicId, 0, appendSpace: true);
					m_DecodeState.m_CurrentInstruction.AppendQuoted(systemId);
				}
				else if (!string.IsNullOrEmpty(systemId))
				{
					m_DecodeState.m_CurrentInstruction.AppendStringWithSpaces(ObxmlInstructionState.sXmlSystem, 0, appendSpace: true, prefixSpace: true);
					m_DecodeState.m_CurrentInstruction.AppendQuoted(systemId);
				}
				m_DecodeState.m_CurrentInstruction.AppendString(ObxmlInstructionState.sXmlTagClosingBracket, 0, appendNewLine: true);
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)285212672, OracleTraceClassName.ObxmlDTDInfo, OracleTraceFuncName.NotationDecl, ex);
				throw;
			}
		}

		internal string PrintAttributeDecl()
		{
			try
			{
				if (m_AttributeList == null || m_AttributeList.Count == 0)
				{
					return m_lastElementString;
				}
				InilializeSubset();
				for (int i = 0; i < m_AttributeList.Count; i++)
				{
					m_DecodeState.m_CurrentInstruction.AppendString(ObxmlInstructionState.sXmlTagAttributeStart, 0, appendNewLine: false, appendSpace: true);
					m_DecodeState.m_CurrentInstruction.AppendStringWithSpaces(m_lastElementString = m_AttributeList[i].ElementName, 0, appendSpace: true);
					m_DecodeState.m_CurrentInstruction.AppendStringWithSpaces(m_AttributeList[i].AttributeName, 0, appendSpace: true);
					if (!string.IsNullOrEmpty(m_AttributeList[i].AttributeString))
					{
						m_DecodeState.m_CurrentInstruction.AppendString(m_AttributeList[i].AttributeString);
					}
					else if (m_AttributeList[i].AttributeStringExpanded)
					{
						m_DecodeState.m_CurrentInstruction.AppendString(m_AttributeList[i].AttributeType);
						if (!string.IsNullOrEmpty(m_AttributeList[i].AttributeMode))
						{
							m_DecodeState.m_CurrentInstruction.AppendStringWithSpaces(m_AttributeList[i].AttributeMode, 0, appendSpace: false, prefixSpace: true);
						}
						if (!string.IsNullOrEmpty(m_AttributeList[i].AttributeValue))
						{
							m_DecodeState.m_CurrentInstruction.AppendQuoted(m_AttributeList[i].AttributeValue, 0, appendSpace: false, prefixSpace: true);
						}
					}
					m_DecodeState.m_CurrentInstruction.AppendString(ObxmlInstructionState.sXmlTagClosingBracket, 0, appendNewLine: true);
				}
				return m_lastElementString;
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)285212672, OracleTraceClassName.ObxmlDTDInfo, OracleTraceFuncName.PrintAttributeDecl, ex);
				throw;
			}
			finally
			{
				if (m_AttributeList != null)
				{
					m_AttributeList.Clear();
				}
			}
		}

		internal override void ClearStateObject()
		{
			IsValid = false;
			m_ElementList.Clear();
			m_AttributeList.Clear();
			m_ObjectList.Clear();
			m_InitSubset = false;
			m_DecodeState = null;
			ObjectName = null;
		}
	}
}
